/**
 * 	 Copyright (c) 2008, 2009 Lukas Zaruba
 * 
 *   This file is part of UniAnalyzer (Universal Analyzer).
 *
 *   UniAnalyzer is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   UniAnalyzer is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public License
 *   along with UniAnalyzer. If not, see <http://www.gnu.org/licenses/>.
 */

package net.zarubsys.unianalyzer.dataminers.lpt.gui.wizard;


import java.util.List;

import net.zarubsys.unianalyzer.dataminers.lpt.gui.parameterObject.PortSettings;
import net.zarubsys.unianalyzer.dataminers.lpt.gui.parameterObject.PreviewData;
import net.zarubsys.unianalyzer.dataminers.lpt.gui.plugin.LPTGUIPlugin;
import net.zarubsys.unianalyzer.dataminers.lpt.pin.CustomizedPin;
import net.zarubsys.unianalyzer.dataminers.lpt.pin.IPin;
import net.zarubsys.unianalyzer.dataminers.lpt.wizard.utils.LPTConsts;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

public class LPTMeasuringPortSetUpPage extends AbstractPageWithContext {
	
	private Label offsetImage;
	private Label imageLabel;
	private Label[] pins = new Label[8];
	
	private Combo addressCombo;
	private Combo offsetCombo;
	private Combo unitsCombo;
	private Text frequency;
	
	private boolean initSequence = false;
	
	public LPTMeasuringPortSetUpPage(String pageName) {
		super(pageName);
	}

	public void createControl(Composite parent) {
		Label label;
		
		Composite container = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.horizontalSpacing = 20;
		container.setLayout(layout);
		
		Group group = new Group(container, SWT.NONE);
		group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
		layout = new GridLayout(2, false);
		layout.horizontalSpacing = 20;
		group.setLayout(layout);
		group.setText(Messages.getString("LPTMeasuringPortSetUpPage.setupDataGroup")); //$NON-NLS-1$
		
		label = new Label(group, SWT.NONE);
		label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		label.setText(Messages.getString("LPTMeasuringPortSetUpPage.portAddress")); //$NON-NLS-1$
		
		addressCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
		GridData gd = new GridData(SWT.BEGINNING, SWT.CENTER, true, false);
		gd.widthHint = 150;
		addressCombo.setLayoutData(gd);
		addressCombo.setItems(LPTConsts.getAddressLabels());
		addressCombo.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				if (initSequence) return;
				Combo c = (Combo) e.widget;
				getMeasurignSettings().getPortSettings().setPortNumber(LPTConsts.getAddressValues()[c.getSelectionIndex()]);
			}
			
		});
		
		label = new Label(group, SWT.NONE);
		label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		label.setText(Messages.getString("LPTMeasuringPortSetUpPage.portOffset")); //$NON-NLS-1$
		
		offsetCombo = new Combo(group, SWT.DROP_DOWN | SWT.READ_ONLY);
		gd = new GridData(SWT.BEGINNING, SWT.CENTER, true, false);
		gd.widthHint = 150;
		offsetCombo.setLayoutData(gd);
		offsetCombo.setItems(LPTConsts.getPortOffsets());
		offsetCombo.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				if (initSequence) return;
				int index = ((Combo) e.widget).getSelectionIndex();
				getMeasurignSettings().getPortSettings().setPortOffset(index);
				PreviewData pData = PreviewData.getPreviewData(index);
				List<CustomizedPin> cPins = PreviewData.createCustomizedPins(pData);
				getMeasurignSettings().setCustomizedPins(cPins);
				setPreviewData(pData);
			}

		});
		
		label = new Label(group, SWT.NONE);
		label.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		label.setText(Messages.getString("LPTMeasuringPortSetUpPage.frequency")); //$NON-NLS-1$
		
		Composite frequencyComposite = new Composite(group, SWT.NONE);
		frequencyComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		layout = new GridLayout(2, false);
		frequencyComposite.setLayout(layout);
		
		frequency = new Text(frequencyComposite, SWT.SINGLE | SWT.BORDER);
		gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
		gd.widthHint = 60;
		frequency.setLayoutData(gd);
		frequency.setToolTipText(Messages.getString("LPTMeasuringPortSetUpPage.errorFrequencyValues")); //$NON-NLS-1$
		frequency.addModifyListener(new ModifyListener() {
			
			public void modifyText(ModifyEvent e) {
				if (initSequence) return;
				try {
					String text = ((Text) e.widget).getText();
					getMeasurignSettings().getPortSettings().setFrequency(Integer.parseInt(text));
				} catch (NumberFormatException error) {
					getMeasurignSettings().getPortSettings().setFrequency(-1);
				}
				validate();
			}
			
		});
		
		unitsCombo = new Combo(frequencyComposite, SWT.DROP_DOWN | SWT.READ_ONLY);
		gd = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
		gd.widthHint = 70;
		unitsCombo.setLayoutData(gd);
		unitsCombo.setItems(LPTConsts.getFrequencyUnitsLabels());
		unitsCombo.addModifyListener(new ModifyListener() {

			public void modifyText(ModifyEvent e) {
				if (initSequence) return;
				Combo tempCombo = (Combo) e.widget;
				int index = tempCombo.getSelectionIndex();
				PortSettings portSettings = getMeasurignSettings().getPortSettings();
				portSettings.setUnitsComboValue(LPTConsts.getFrequencyUnitsValues()[index]);
				portSettings.setUnitsComboValueDescription(LPTConsts.getFrequencyUnitsLabels()[index]);
				validate();
			}
			
		});
		
		Group previewGroup = new Group(container, SWT.NONE);
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		previewGroup.setLayoutData(gd);
		previewGroup.setLayout(new GridLayout(2, true));
		previewGroup.setText(Messages.getString("LPTMeasuringPortSetUpPage.preview")); //$NON-NLS-1$
		
		Composite imageComposite = new Composite(previewGroup, SWT.NONE);
		imageComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
		imageComposite.setLayout(new GridLayout(1, false));
		
		imageLabel = new Label(imageComposite, SWT.NONE);
		gd = new GridData(SWT.CENTER, SWT.TOP, false, false);
		gd.widthHint = 180;
		imageLabel.setLayoutData(gd);
		
		offsetImage = new Label(imageComposite, SWT.NONE);
		offsetImage.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, false, false));
		
		Composite pinsComposite = new Composite(previewGroup, SWT.NONE);
		pinsComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
		pinsComposite.setLayout(new GridLayout(1, false));
		createPins(pinsComposite);
		
		setupDefaultValues();
		validate();
		setControl(container);
	}
	
	private void createPins(Composite group) {
		for (int i = 0; i < 8; i++) {
			Label label = new Label(group, SWT.NONE);
			GridData gd = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
			gd.widthHint = 150;
			label.setLayoutData(gd);
			label.setText(String.valueOf(i));
			pins[i] = label;
		}
	}

	private void validate() {
		PortSettings ps = getMeasurignSettings().getPortSettings();
		int resultFrequency = ps.getFrequency() * ps.getUnitsComboValue();
		if (resultFrequency < 1 || resultFrequency > 400000) {
			setUserOutput(Messages.getString("LPTMeasuringPortSetUpPage.errorFrequency")); //$NON-NLS-1$
			return;
		}
		setUserOutput(null);
	}
	
	private void setPreviewData(PreviewData data) {
		imageLabel.setText(data.getImageDescription());
		offsetImage.setImage(LPTGUIPlugin.getDefault().getImage(data));
		for (int i = 0; i < pins.length; i++) {
			Label pinLabel = pins[i];
			IPin pin = data.getPin(i);
			pinLabel.setText(pin.getLabel());
			pinLabel.setEnabled(!pin.isReserved());
		}
	}
	
	private void setupDefaultValues() {
		initSequence = true;
		PortSettings portSettings = getMeasurignSettings().getPortSettings();
		int portOffset = portSettings.getPortOffset();
		setPreviewData(PreviewData.getPreviewData(portOffset));
		offsetCombo.select(portOffset);
		addressCombo.select(LPTConsts.findValueIndex(LPTConsts.getAddressValues(), 
				portSettings.getPortNumber()));
		unitsCombo.select(LPTConsts.findValueIndex(LPTConsts.getFrequencyUnitsValues(), 
				portSettings.getUnitsComboValue()));
		frequency.setText(String.valueOf(portSettings.getFrequency()));
		initSequence = false;
	}

}